package com.sname.demoribbon.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.ObservableExecutionMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import rx.Observable;
import rx.Subscriber;

import java.util.concurrent.ExecutionException;

/**
 * Created By  醉美柳舞之众星捧月
 *
 * @author 宋贤坤
 * @date 2018/11/18 19:53
 */
@Service
public class AllowCircuitBreaker {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * fallbackMethod = ""表示请求降级
     *
     * @return
     */
    @HystrixCommand(fallbackMethod = "toCircuitBreaker", observableExecutionMode = ObservableExecutionMode.LAZY)
    public String helloService(String ssss) {
        return restTemplate.getForEntity("http://DEMO-UPMS/hello", String.class).getBody();
    }

    public String toCircuitBreaker() {
        return "降级啦降级啦降级啦降级啦降级啦降级啦降级啦！！！！";
    }


    @HystrixCommand(fallbackMethod = "helloFallBack", observableExecutionMode = ObservableExecutionMode.LAZY)
    public Observable<String> helloService() throws ExecutionException, InterruptedException {
////        return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody();
//        /**改造：*/
//        Future<String> future = new AsyncResult<String>() {
//            @Override
//            public String invoke() {
//                return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody();
//            }
//        };
//        return future.get();

        // 再次注释掉,再次改造:上面的代码,是用代码实现热(冷)执行;下面的代码就是通过注解的方式来实现冷热执行

        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                // 如果订阅了才执行这个逻辑,如果没有订阅就算了
                try {
                    if (!subscriber.isUnsubscribed()) {
                        System.out.println("方法执行!");
                        // 多个请求用onNext串起来
                        String result = restTemplate.getForEntity("http://DEMO-UPMS/hello", String.class).getBody();
                        // 订阅方法,onNext(result);是传递请求,将请求返回回去
                        subscriber.onNext(result);
                        // 如果有多个方法需要订阅,
                        String result1 = restTemplate.getForEntity("http://DEMO-UPMS/hello", String.class).getBody();
                        subscriber.onNext(result1);
                        // 当多个方法执行完了后：
                        subscriber.onCompleted();
                        // onCompleted();表示已经执行完毕,要是后面还有OnNext()的话虽然不会报错但是也不得执行了
                    }
                } catch (RestClientException e) {
                    subscriber.onError(e);
                }
            }
        });
    }

    public String helloFallBack() {
        return "Error::::: <<<观察者模式>>> :::::已经服务降级";
    }
}
